import React, { PureComponent, createRef } from 'react';
import { Col, Button } from 'antd';
import { DownOutlined, UpOutlined } from '@ant-design/icons';
import router from 'umi/router';
import Field from './Field';
/**
 * handle前缀方法，可以在原始组件中内置相同名称（去掉TL）方法重置掉默认行为
 */

export default ({ namespace }) => WrappedComponent => {
  /**
   * 类型制造者
   * @param {string} type
   */
  const TypeMaker = type => `${namespace}/${type}`;
  return class TableList extends PureComponent {
    tableListRef = createRef();

    constructor(props) {
      super(props);
      this.state = {};
      this.handleTLSearch = this.handleTLSearch.bind(this);
    }

    get tableList() {
      return this.tableListRef.current;
    }

    get searchForm() {
      return this.tableList.formRef.current;
    }

    /**
     * 生成查询表单域
     * @param {object} param0
     */
    renderTLFields = ({ fields, expand, count }) => {
      const children = [];
      fields.forEach((field, index) => {
        // 收起模式超过最大值就不再渲染
        if (!expand && index + 1 > count) {
          return false;
        }
        children.push(<Field {...field} />);
      });
      return children;
    };

    renderTLFieldsButton = () => {
      const { expand } = this.props[namespace].searchForm;
      return expand ? this.renderExpandButton() : this.renderUnExpandButton();
    };

    renderExpandButton = () => (
      <Col
        span={24}
        style={{
          textAlign: 'right',
          marginBottom: 24,
        }}
      >
        <Button type="primary" htmlType="submit">
          查询
        </Button>
        <Button
          style={{
            margin: '0 8px',
          }}
          onClick={() => {
            this.handleTLFormReset();
          }}
        >
          重置
        </Button>
        <a
          onClick={() => {
            this.handleTLToggleForm();
          }}
        >
          <>
            收起
            <UpOutlined />
          </>
        </a>
      </Col>
    );

    renderUnExpandButton = () => (
      <Col span={8}>
        <Button type="primary" htmlType="submit">
          查询
        </Button>
        <Button
          style={{
            margin: '0 8px',
          }}
          onClick={() => {
            this.handleTLFormReset();
          }}
        >
          重置
        </Button>
        <a
          onClick={() => {
            this.handleTLToggleForm();
          }}
        >
          <>
            展开
            <DownOutlined />
          </>
        </a>
      </Col>
    );

    handleTLFormOnfinish = () => {
      this.handleTLSearch();
    };

    /**
     * 查询表单重置
     */
    handleTLFormReset = async () => {
      const { dispatch } = this.props;
      const defaultValues = this.props[namespace]?.searchForm?.defaultValues;
      await dispatch({
        type: TypeMaker('setInitialValues'),
        payload: { initialValues: {...defaultValues} },
      });
      this.searchForm.resetFields();
      // 可以给form设置默认值，自定义重置方法意义不大
      if (this.tableList.handleFormReset) {
        this.tableList.handleFormReset();
      }
    };

    // 表格有变化：比如：切换页码
    handleTLTableChange = async (pagination, filtersArg, sorter) => {
      await this.props.dispatch({
        type: TypeMaker('setTLChange'),
        payload: { pagination, sorter },
      });
      this.handleTLSearch(pagination.current, pagination.pageSize, false);
    };

    /**
     * 切换表格展开收起
     */
    handleTLToggleForm = () => {
      this.props.dispatch({
        type: TypeMaker('toggleTLExpand'),
      });
    };

    /**
     * 选择行
     * @param {array} rows
     * @param {array} rowKeys
     */
    handleTLSelectRows = (rows, rowKeys) => {
      const { dispatch } = this.props;

      dispatch({
        type: TypeMaker('setTLSelectRow'),
        payload: {
          selectedRows: rows,
          selectedRowKeys: rowKeys,
        },
      });
    };

    handleTLClearSelectRows = () => {
      const { dispatch } = this.props;
      dispatch({
        type: TypeMaker('clearTLSelectRow'),
      });
    };

    /**
     * 切换tab
     * @param {string} activeKey
     */
    handleTLTabChange = async activeKey => {
      const { dispatch, location } = this.props;
      router.push({
        pathname: location.pathname,
        query: {
          activeKey,
        },
      });
      await dispatch({
        type: TypeMaker('setTabActiveKey'),
        payload: { activeKey },
      });
      this.handleTLSearch();
    };

    /**
     * 查询
     * @param {number} current
     * @param {number} pageSize
     */
    handleTLSearch(current = 1, pageSize = 10, isClear, ...rest) {
      /* eslint-disable prefer-rest-params */
      if (this.tableList.handleSearch) {
        this.tableList.handleSearch(current, pageSize, isClear, ...rest);
      } else {
        const { dispatch } = this.props;
        const { tab, tableList } = this.props[namespace];
        const fieldsValue = this.searchForm.getFieldsValue();

        const payload = {
          data: {
            pageArg: {
              currentPage: current,
              pageSize,
            },
            pageOrdBys: tableList.orderBy,
            ...fieldsValue,
            ...rest,
          },
        };
        // 分tab的
        if (tab.use) {
          payload[tab.name] = tab.activeKey;
        }

        dispatch({
          type: TypeMaker('setInitialValues'),
          payload: {
            initialValues: fieldsValue,
          },
        });
        dispatch({
          type: TypeMaker('debounceFetchTableList'),
          payload,
        });
      }
    }

    /**
     * 刷新当前页
     */
    async handleTLRefresh() {
      const pagination = this.props[namespace].tableList.pagination;
      const { current, pageSize } = pagination;
      this.handleTLSearch(current, pageSize);
    }

    doSearch() {
      /* eslint-disable prefer-rest-params */
      if (this.tableList.handleSearch) {
        this.tableList.handleSearch.apply(this, arguments);
      } else {
        /* eslint-disable prefer-spread */
        this.handleTLSearch.apply(this, arguments);
      }
    }

    render() {
      const hocProps = {
        renderTLFields: this.renderTLFields,
        renderTLFieldsButton: this.renderTLFieldsButton,
        handleTLSearch: this.handleTLSearch,
        handleTLFormOnfinish: this.handleTLFormOnfinish,
        handleTLFormReset: this.handleTLFormReset,
        handleTLToggleForm: this.handleTLToggleForm,
        handleTLSelectRows: this.handleTLSelectRows,
        handleTLClearSelectRows: this.handleTLClearSelectRows,
        handleTLTableChange: this.handleTLTableChange,
        handleTLTabChange: this.handleTLTabChange,
        handleTLRefresh: this.handleTLRefresh,
      };
      return <WrappedComponent ref={this.tableListRef} {...this.props} {...hocProps} />;
    }
  };
};
